package com.cauli.manage.storage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cauli.manage.config.mapper.ConfigMapper;
import com.cauli.manage.config.model.entity.Config;
import com.cauli.manage.storage.mapper.StorageMapper;
import com.cauli.manage.storage.model.dto.StorageAddDTO;
import com.cauli.manage.storage.model.dto.StorageDTO;
import com.cauli.manage.storage.model.dto.StorageQueryDTO;
import com.cauli.manage.storage.model.dto.StorageUpdateDTO;
import com.cauli.manage.storage.model.dto.StorageUpdateStatusDTO;
import com.cauli.manage.storage.model.entity.Storage;
import com.cauli.manage.storage.service.StorageService;
import com.cauli.utils.exception.MyException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author Cauli
 * @date 2023-3-28 15:16:02
 * @description 存储源 服务实现类
 */
@Slf4j
@Service
public class StorageServiceImpl extends ServiceImpl<StorageMapper, Storage> implements StorageService {
    @Autowired
    private ConfigMapper configMapper;

    @Value("${ufop.storage-type}")
    private Integer storageType;

    @Override
    public Page<Storage> getStoragePage(StorageQueryDTO storageQueryDTO) {
        return baseMapper.selectPage(storageQueryDTO.toPage(), storageQueryDTO.toLambdaQueryWrapper());
    }

    @Override
    public StorageDTO getStorageById(Long storageId) {
        Storage storage = baseMapper.selectById(storageId);
        StorageDTO storageDTO = new StorageDTO();
        if (storage != null) {
            BeanUtils.copyProperties(storage, storageDTO);
        }
        return storageDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addStorage(StorageAddDTO storageAddDTO) {
        Storage storage = new Storage();
        BeanUtil.copyProperties(storageAddDTO, storage);
        baseMapper.insert(storage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStorage(StorageUpdateDTO storageUpdateDTO) {
        // 根据存储源ID获取存储源信息
        Storage storage = baseMapper.selectById(storageUpdateDTO.getStorageId());
        BeanUtil.copyProperties(storageUpdateDTO, storage);
        if (storage == null) {
            throw new MyException("存储源不存在");
        }
        baseMapper.updateById(storage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeStorageStatus(StorageUpdateStatusDTO storageUpdateStatusDTO) {
        // 根据存储源ID获取存储源信息
        Storage storage = baseMapper.selectById(storageUpdateStatusDTO.getStorageId());
        if (storage == null) {
            throw new MyException("存储源不存在");
        }
        BeanUtil.copyProperties(storageUpdateStatusDTO, storage);
        baseMapper.updateById(storage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteStorage(List<Long> storageIds) {
        for (Long storageId : storageIds) {
            // 根据存储源ID获取存储源信息
            Storage storage = baseMapper.selectById(storageId);
            baseMapper.deleteById(storage);
        }
    }

    @Override
    public Long getTotalStorageSize(Long userId) {
        // 根据用户ID获得总存储大小
        return this.getTotalStorage(userId);
    }

    /**
     * 根据用户ID获得总存储大小
     *
     * @param userId
     * @return
     */
    private Long getTotalStorage(Long userId) {
        LambdaQueryWrapper<Storage> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Storage::getUserId, userId);
        Storage storage = baseMapper.selectOne(lambdaQueryWrapper);
        Long totalStorageSize;
        // 如果没有存储源
        if (storage == null) {
            // 获得默认存储大小
            LambdaQueryWrapper<Config> configLambdaQueryWrapper = new LambdaQueryWrapper<>();
            configLambdaQueryWrapper.eq(Config::getConfigName, "totalStorageSize");
            Config config = configMapper.selectOne(configLambdaQueryWrapper);
            totalStorageSize = Long.parseLong(config.getConfigValue());

            // 新增存储源
            storage = new Storage();
            storage.setUserId(userId);
            storage.setStorageType(storageType);
            storage.setTotalStorageSize(totalStorageSize);
            storage.setStatus(1);
            baseMapper.insert(storage);
        } else if (storage.getStatus() != 1) {
            // 如果存储源被禁用
            throw new MyException("您的存储源被禁用，无法上传文件，请联系管理员处理！");
        } else {
            // 有存储源且正常，则更新存储源类型
            storage.setStorageType(storageType);
            baseMapper.updateById(storage);

            totalStorageSize = storage.getTotalStorageSize();
        }
        if (totalStorageSize != null) {
            totalStorageSize = totalStorageSize * 1024 * 1024;
        }

        return totalStorageSize;
    }
}
